package cn.wolfcode.wolf2w.controller;


import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.Travel;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.search.domain.DestinationEs;
import cn.wolfcode.wolf2w.search.domain.StrategyEs;
import cn.wolfcode.wolf2w.search.domain.TravelEs;
import cn.wolfcode.wolf2w.search.domain.UserInfoEs;
import cn.wolfcode.wolf2w.search.qo.SearchQueryObject;
import cn.wolfcode.wolf2w.search.service.*;
import cn.wolfcode.wolf2w.search.vo.SearchResultVO;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.service.ITravelService;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.JsonResult;
import cn.wolfcode.wolf2w.util.ParamMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class SearchController {
    /**
     * 两个参数1搜索的类型   2搜索的关键字 因为返回Page,所以封装为qo对象比较合适
     *
     * @return
     */
//es服务

    @Autowired
    private IDestinactionEsService destinationEsService;
    @Autowired
    private IStrategyEsService strategyEsService;

    @Autowired
    private ITravelEsService travelEsService;

    @Autowired
    private IUserInfoEsService userInfoEsService;


    //mongodb服务
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private ITravelService travelService;
    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private ISearchService searchService;

    @GetMapping("/q")
    public Object search(SearchQueryObject qo) throws UnsupportedEncodingException {
        //根据不同的查询类型执行不同的服务方法
        String key= URLDecoder.decode(qo.getKeyword(), "utf-8");
        qo.setKeyword(key);
        switch (qo.getType()) {
            case SearchQueryObject.TYPE_DEST:
                return searchDest(qo);
            case SearchQueryObject.TYPE_STRATEGY:
                return searchStra(qo);
            case SearchQueryObject.TYPE_TRAVEL:
                return searchTravel(qo);
            case SearchQueryObject.TYPE_USER:
                return searchUser(qo);
            default:
                return searchAll(qo);
        }
    }

    //全部
    private Object searchAll(SearchQueryObject qo) {
        SearchResultVO result = new SearchResultVO();
        Page<UserInfo> us = searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME,
                UserInfo.class,qo,"info",  "city"
        );
        Page<Travel> ts = searchService.searchWithHighlight(TravelEs.INDEX_NAME,  TravelEs.TYPE_NAME,
                Travel.class,qo, "title",  "summary"
        );

        for (Travel travel : ts.getContent()) {
            travel.setAuthor(userInfoService.get(travel.getUserId()));
        }
        Page<Strategy> sts = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME,
                Strategy.class,qo, "title", "subTitle", "summary"
        );
        Page<Destination> ds = searchService.searchWithHighlight(
                DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME,    Destination.class,
                qo, "name", "info"
        );
        result.setUsers(us.getContent());
        result.setTravels(ts.getContent());
        result.setStrategys(sts.getContent());
        result.setDests(ds.getContent());
        result.setTotal(us.getTotalElements()
                + ts.getTotalElements() + sts.getTotalElements() + ds.getTotalElements());
        return JsonResult.success(new ParamMap().put("result",result ).put("qo",qo));
    }

    private Object searchUser(SearchQueryObject qo) {
        Page<UserInfo> page = searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME, UserInfo.class, qo,
                "city", "info");
        return JsonResult.success(new ParamMap().put("page", page).put("qo", qo));
    }

    private Object searchTravel(SearchQueryObject qo) {
        Page<Travel> page = searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME, Travel.class, qo,
                "title", "summary");
        return JsonResult.success(new ParamMap().put("page", page).put("qo", qo));
    }

    private Object searchStra(SearchQueryObject qo) {
        //查攻略
        Page<Strategy> page = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME, Strategy.class, qo,
                "title", "subTitle", "summary");
        return JsonResult.success(new ParamMap().put("page", page).put("qo", qo));
    }

    private Object searchDest(SearchQueryObject qo) {
        //并不牵扯es操作,从MongoDB中查数据
        //1:通过关键字查询目的地是否存在
        Destination dest = destinationService.getByName(qo.getKeyword());
        //如果存在查询该目的地下所有的攻略,游记,放在vo中
        SearchResultVO vo = new SearchResultVO();
        if (dest!=null) {
            //攻略
            List<Strategy> sts = strategyService.selectByDestId(dest.getId());
            vo.setStrategys(sts);
            //游记
            List<Travel> ts = travelService.queryByDestName(qo.getKeyword());
            vo.setTravels(ts);
            //某个城市用户
            List<UserInfo> us = userInfoService.queryByCityName(qo.getKeyword());
            vo.setUsers(us);
            //求出总数
            long total = sts.size() + ts.size() + us.size();
            vo.setTotal(total);
        }else {
            return JsonResult.defaultError();
        }
        //加进map传入后端
        Map<String,Object> map=new HashMap<>();
        map.put("result", vo);
        map.put("qo", qo);
        map.put("dest", dest);
        return JsonResult.success(map);
    }
}
